﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Domain.Model;

using Presentation.Models;
using Presentation.Models.Binders;

namespace Presentation.Controllers
{
    public class SubprojectController : AbstractController
    {
        // --------------------------------------
        // Constructor
        // --------------------------------------

        public SubprojectController()
            : base()
        { }

        // --------------------------------------
        // Actions
        // --------------------------------------

        //
        // GET: /Subproject/

        public ActionResult Index()
        {
            return RedirectToAction("Index", "Portfolio");
        }

        //
        // GET: /Subproject/Create
         [Authorize(Roles = "admins")]
        public ActionResult Create(int projectId)
        {
            var subproject = new Subproject();
            var form = formManager.GetSubprojectForm();

            CreateSubprojectDetails(subproject, form);

            var model = new SubprojectViewModel
            {
                ProjectId = projectId,
                Subproject = subproject,
                Form = form
            };

            return View(model);
        }

        //
         // POST: /Subproject/Create//Salman has edited the code here for validation
        [HttpPost]
        public ActionResult Create([ModelBinder(typeof(SubprojectViewModelBinding))] SubprojectViewModel model)
        {
            try
            {
                if (!ValidateInput(model, formManager.GetSubprojectForm()))
                {
                    model.Form = formManager.GetSubprojectForm();
                    return View(model);
                }

                projectManager.AddSubproject(model.ProjectId, model.Subproject);

                return RedirectToAction("Edit", "Project", new { id = model.ProjectId});
            }
            catch (Exception e)
            {
                return View("Error");
            }
        }

        //Function to validate inputs
        public static bool ValidateInput(SubprojectViewModel model, Form form)
        {
            for (int i = 0; i < model.Subproject.Details.Count; i++)
            {
                try
                {
                    if (model.Subproject.Details[i].Value == null)
                    {
                        var errmsg = "A field can not be empty.";
                        model.errmsg = errmsg;
                        model.errindex = i;
                        return false;
                    }
                    else if (form.FormElements[i].Type.Equals("typeChar"))
                    {
                        //checking if value entered is text.
                        try
                        {
                            double d;
                            d = System.Double.Parse(model.Subproject.Details[i].Value);
                            var errmsg = "Numeric value is not acceptable in a text field.";
                            model.errmsg = errmsg;
                            model.errindex = i;
                            return false;
                        }
                        catch (Exception e)
                        {
                        }
                    }
                    else if (form.FormElements[i].Type.Equals("typeNumeric"))
                    {
                        //checking if value entered is Numeric.
                        try
                        {
                            double d;
                            d = System.Double.Parse(model.Subproject.Details[i].Value);
                        }
                        catch (Exception e)
                        {
                            var errmsg = "Text value is not acceptable in a numeric field.";
                            model.errmsg = errmsg;
                            model.errindex = i;
                            return false;
                        }
                    }
                    else if (form.FormElements[i].Type.Equals("typeDate"))
                    {
                        //checking if value entered is a Date.
                        try
                        {
                            short res = IsDate(model.Subproject.Details[i].Value);
                            var errmsg = "";
                            if (res != 0) //if it is a valid date, res will hold 0
                            {
                                if (res == 1)//if date is an older fied, res will hold 1
                                    errmsg = "Date can not be an older date.";
                                else //if date is in invalid format, res will hold 2
                                    errmsg = "Please enter a valid date in Date field e.g. DD/MM/YYYY";
                                model.errmsg = errmsg;
                                model.errindex = i;
                                return false;
                            }
                        }
                        catch (Exception e)
                        {
                        }
                    }

                }
                catch (Exception e)
                {
                }
            }
            return true;
        }
        //this function is for ensuring if valid date is entered. added by salman
        public static short IsDate(Object obj)
        {
            string strDate = obj.ToString();
            short res = 0;
            try
            {//esuring that it is not an old date.
                DateTime dt = DateTime.Parse(strDate);
                if (dt.Year < System.DateTime.Now.Year)
                    res = 1;
                else if (dt.Year == System.DateTime.Now.Year)
                {
                    if (dt.Month < System.DateTime.Now.Month)
                        res = 1;
                    else if (dt.Month == System.DateTime.Now.Month)
                    {
                        if (dt.Day < System.DateTime.Now.Day)
                            res = 1;
                        else
                            res = 0;//success
                    }
                    else
                        res = 0;//success
                }
                else
                    res = 0;//success
            }
            catch
            {
                res = 2;
            }
            return res;
        }

        //
        // GET: /Subproject/Edit
         [Authorize(Roles = "admins")]
        public ActionResult Edit(int id)
        {
            var model = CreateViewModel(id);

            CreateSubprojectDetails(model.Subproject, model.Form);

            return View(model);
        }

        //
        // POST: /Subproject/Edit
        [HttpPost]
        public ActionResult Edit([ModelBinder(typeof(SubprojectViewModelBinding))] SubprojectViewModel model)
        {
            if (model.Subproject != null)
            {
                try
                {
                    if (!ValidateInput(model, formManager.GetSubprojectForm())) //validating input in edit form by salman
                    {
                        model.Form = formManager.GetSubprojectForm();
                        return View(model);
                    }
                    subprojectManager.UpdateSubproject(model.ProjectId, model.Subproject);

                    return RedirectToAction("Edit", "Project", new { id = model.ProjectId });

                }
                catch (Exception e)
                {
                    return View("Error");
                }

            }

            return View("Error");
        }

        //
        // GET: /Subproject/View

        public ActionResult View(int id)
        {
            var model = CreateViewModel(id);

            CreateSubprojectDetails(model.Subproject, model.Form);

            return View(model);
        }

        //
        // GET: /Subproject/Delete
         [Authorize(Roles = "admins")]
        public ActionResult Delete(int id, int projectId)
        {
            try
            {
                subprojectManager.DeleteSubproject(id);

                return RedirectToAction("Edit", "Project", new { id = projectId });
            }
            catch (Exception e)
            { 
              return View("Error");
            }
        }

        //
        // GET: /Subproject/AddTask
         [Authorize(Roles = "admins")]
        public ActionResult AddTask(int subprojectId)
        {
            var model = CreateViewModel(subprojectId);

            return View(model);
        }

        //
        // POST: /Subproject/AddTask
        [HttpPost]
        public ActionResult AddTask([ModelBinder(typeof(SubprojectViewModelBinding))] SubprojectViewModel model)
        {
            try
            {
                subprojectManager.AddSubprojectTask(model.Subproject.Id, model.Task);

                return RedirectToAction("Edit", new { id = model.Subproject.Id });
            }
            catch (Exception e)
            {
                return View("Error");
            }
        }

        //
        // GET: /Subproject/EditTask
         [Authorize(Roles = "admins")]
        public ActionResult EditTask(int id)
        {
            return View(subprojectManager.GetSubprojectTaskById(id));
        }

        //
        // POST: /Subproject/EditTask
        [HttpPost]
        public ActionResult EditTask(SubprojectTask task)
        {
            try
            {
                var subproject = subprojectManager.GetSubprojectById(task.Subproject.Id);
                if (subproject != null)
                {
                    subprojectManager.UpdateSubprojectTask(subproject.Id, task);
                }

                return RedirectToAction("Edit", "Subproject", new { id = task.Subproject.Id });
            }
            catch (Exception e)
            {
                return View("Error");
            }
        }

        //
        // GET: /Subproject/DeleteTask
         [Authorize(Roles = "admins")]
        public ActionResult DeleteTask(int id)
        {
            try
            {
                var task = subprojectManager.GetSubprojectTaskById(id);
                var subproject = subprojectManager.GetSubprojectById(task.Subproject.Id);
                if (subproject != null)
                {
                    subprojectManager.DeleteSubprojectTask(subproject.Id, task);
                }

                return RedirectToAction("Edit", "Subproject", new { id = subproject.Id });
            }
            catch (Exception e)
            {
                return View("Error");
            }
        }

        // --------------------------------------
        // Private methods
        // --------------------------------------
        #region Private methods

        /// <summary>
        /// Creates all SubprojectDetail objects, that are
        /// missing corresponding to the Subproject Form.
        /// </summary>
        /// <param name="subproject"></param>
        /// <param name="form"></param>
        private void CreateSubprojectDetails(Subproject subproject, Form form)
        {
            foreach (var item in form.FormElements)
            {
                var projectDetail = subproject.GetDetailByName(item.Name);

                if (projectDetail == null)
                {
                    subproject.AddDetail(item.Name);
                }
            }
        }

        private SubprojectViewModel CreateViewModel(int subprojectId)
        {
            var subproject = subprojectManager.GetSubprojectById(subprojectId);
            var projectId = subproject.Project.Id;

            var model = new SubprojectViewModel
            {
                ProjectId = projectId,
                Subproject = subproject,
                Form = formManager.GetSubprojectForm(),
                Task = new SubprojectTask()
            };

            return model;
        }

        #endregion
    }
}
